/*	$Id: fan.c,v 1.1.1.1 2006/09/14 01:59:08 xqch Exp $ */
/*
 * Copyright (c) 2001 Opsycon AB  (www.opsycon.se)
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by Opsycon AB, Sweden.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/device.h>
#include <sys/queue.h>

#include <pmon.h>

unsigned char
cmd_pcietest(ac, av)
	int ac;
	char *av[];
{
	unsigned int port, gen;
	volatile unsigned char * base;
	volatile unsigned int * pcie_clock_source;

	if (ac != 3){
	  printf("Usage:pcietest <port > <gen> \n");
	  return 0;
	}

#if 0
	sscanf(av[1], "%08lx", &port);
	sscanf(av[2], "%08lx", &gen);
#else
	port = atoi(av[1]);
	gen = atoi(av[2]);
#endif

	// m4 0xbbd0022c 0x0f000000 to use pcie clock
	pcie_clock_source = (volatile unsigned int *)(0xbfd0022c);
	*pcie_clock_source = 0x0f000000;

	base = (volatile unsigned char *)(0xb8110000 + port * 0x100);
	
	// tx rx reset
	*(base) = 0x30;

	// output_ena, power_mode, nearfelb
	*(base + 0x10) = 0x0e;
	*(base + 0x11) = 0x21;

	// auto test
	*(base + 0x13) = 0x03;
	
	// tx rx reset da-assert
	*(base) = 0x10;
	*(base) = 0x00;
	
	if ( gen == 1 )	
	  *(base + 0x12) = 0x01;
	if ( gen == 2 )	
	*(base + 0x12) = 0x02;

	printf("LS2H PCIE port%d gen %d test done\n", port, gen);

	return(1);
}

cmd_satatest(ac, av)
	int ac;
	char *av[];
{
	
	unsigned int port, gen;
	volatile unsigned char * base;

	if (ac != 3){
	  printf("Usage:satatest <port > <gen> \n");
	  return 0;
	}

#if 0
	sscanf(av[1], "%08lx", &port);
	sscanf(av[2], "%08lx", &gen);
#else
	port = atoi(av[1]);
	gen = atoi(av[2]);
#endif

	base = (volatile unsigned char *)(0xbfe38000 + port * 0x100);
	
	// tx rx reset
	*(base) = 0x30;

	// output_ena, power_mode, nearfelb
	*(base + 0x10) = 0x0e;
	*(base + 0x11) = 0x21;

	// auto test
	*(base + 0x13) = 0x03;
	
	// tx rx reset da-assert
	*(base) = 0x10;
	*(base) = 0x00;
	
	if ( gen == 1 )	
	  *(base + 0x12) = 0x00;
	if ( gen == 2 )	
	*(base + 0x12) = 0x01;

	printf("LS2H SATA port%d gen %d test done\n", port, gen);
	return(1);

}

/*
 *
 *  Command table registration
 *  ==========================
 */

static const Cmd Cmds[] =
{
	{"Misc"},
	{"pcietest",	"", 0, "ls2h pcietest: pcietest [0/1/2/3] [1/2]", cmd_pcietest, 1, 99, 0},
	{"satatest",	"", 0, "ls2h satatest: satatest [0/1/2/3] [1/2]", cmd_satatest, 1, 99, 0},
	{0, 0}
};

static void init_cmd __P((void)) __attribute__ ((constructor));

void
init_cmd()
{
	cmdlist_expand(Cmds, 1);
}
